package xs.szw.common.utils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import xs.szw.common.result.Result;
import xs.szw.common.result.ResultCode;

import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;


/**
 * @program: My_SpringSecurity
 * @description: 响应结果工具类
 * @author: Songzw
 * @create: 2025-02-01 13:56
 **/
@Slf4j
public class ServletUtils {


    /**
     * 该函数用于将字符串作为 HTTP 请求的响应进行渲染。
     * 它会设置 HTTP 状态码、内容类型和响应的字符编码，
     * 然后将提供的字符串写入响应的写入器。
     *
     * @param response 代表 HTTP 响应的 HttpServletResponse 对象。
     * @param string 要作为响应呈现的字符串。
     * @param code 要为响应设置的 HTTP 状态码。
     */
    public static String renderString(HttpServletResponse response, String string, int code) {
        try
        {
            response.setStatus(code);
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(string);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return null;
    }

    public static void writeErrMsg(HttpServletResponse response, ResultCode resultCode) {
        int status = getHttpStatus(resultCode);

        response.setStatus(status);
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());

        try (PrintWriter writer = response.getWriter()) {
            String jsonResponse = JSONUtil.toJsonStr(Result.fail(resultCode));
            writer.print(jsonResponse);
            writer.flush(); // 确保将响应内容写入到输出流
        } catch (IOException e) {
            log.error("响应异常处理失败", e);
        }
    }

    /**
     * 根据结果码获取HTTP状态码
     *
     * @param resultCode 结果码
     * @return HTTP状态码
     */
    private static int getHttpStatus(ResultCode resultCode) {
        return switch (resultCode) {
            case ACCESS_DENIED, ACCESS_TOKEN_INVALID, REFRESH_TOKEN_INVALID -> HttpStatus.UNAUTHORIZED.value();
            default -> HttpStatus.BAD_REQUEST.value();
        };
    }

    /**
     * 获取客户端IP
     * @param request
     * @return
     */
    public static String getIpAddress(HttpServletRequest request) {
        //没有nginx反向代理直接获取真实ip
        String remoteAddr = request.getRemoteAddr();
        if(!StrUtil.isBlank(remoteAddr)){
            return remoteAddr;
        }
        //请求经过了反向代理（如 Nginx、Apache），IP 地址通常会被放在 X-Forwarded-For 或 X-Real-IP 等请求头
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
// 获取到多个ip时取第一个作为客户端真实ip
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0];
        }
        return ip;
    }

}
